package com.je.app.control;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.table.DefaultTableModel;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import com.je.app.control.interfaces.ControlStockInterface;
import com.je.app.model.AltaConsumicion;
import com.je.app.model.BajaConsumicion;
import com.je.app.model.Consumicion;
import com.je.app.model.Sesion;
import com.je.app.persistence.DaoStock;
import com.je.app.view.MainFrame;
import com.je.app.view.MainFrame.MessageType;
import com.je.app.view.Stock;
import com.je.app.view.StockAdministracion;

public class ControlStock implements ControlStockInterface{

	private static ControlStock instance;
	private MainFrame mainFrame;
	private DaoStock daoStock = DaoStock.getInstance();

	private List <Integer> availableIds = null;
	private List <Integer> allIds = null;
	
	public static ControlStock getInstance(){
		if(instance==null){
			instance = new ControlStock();
		}
		return instance;
	}
	
	private ControlStock(){
		mainFrame = MainFrame.getInstance();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void abrirStock(){
		
		List <Consumicion> list = daoStock.list(Consumicion.class.getName());
		availableIds = new ArrayList <Integer>();
		allIds = new ArrayList <Integer>();
		DefaultTableModel model = new DefaultTableModel(null,new String [] {"Detalle","Precio","Heladera","Dep\u00F3sito"});
		DefaultComboBoxModel<String> availableNames = new DefaultComboBoxModel<String>();
		DefaultComboBoxModel<String> allNames = new DefaultComboBoxModel<String>();
		allNames.addElement("Seleccionar");
		allIds.add(-1);
		availableNames.addElement("Seleccionar");
		availableIds.add(-1);
		for(Consumicion consumicion:list){
			model.addRow(consumicion.toArray());

			allIds.add(consumicion.getIdConsumicion());
			allNames.addElement(consumicion.getNombre());
			
			availableIds.add(consumicion.getIdConsumicion());
			availableNames.addElement(consumicion.getNombre());
		}
		JPanel panel;
		if(!ControlSesion.getInstance().getActiveSesion().getUsuario().isAdministrador())
			panel = new Stock(model,allNames,availableNames);
		else panel = new StockAdministracion(model,allNames,availableNames);
		mainFrame.setPanel(panel);
		
	}

	@SuppressWarnings("rawtypes")
	public void cargarStock(int rowCombo, Date fecha, int cantidadHeladera, int cantidadDeposito, String comentario){

		if(cantidadDeposito>0 && !ControlSesion.getInstance().getActiveSesion().getUsuario().isAdministrador()){
			//Alguien que no es administrador no puede cargar deposito.
			mainFrame.showMessage(MessageType.ERROR,"OPERACION NO PERMITIDA.");
		}
		else
		try{
			int idConsumicion = allIds.get(rowCombo);
			Sesion sesion = ControlSesion.getInstance().getActiveSesion();
			Consumicion consumicion = (Consumicion) daoStock.get(Consumicion.class, idConsumicion);
			AltaConsumicion alta = new AltaConsumicion(0,consumicion,sesion,fecha,cantidadHeladera,cantidadDeposito,comentario);
			daoStock.save(AltaConsumicion.class.getName(),alta);
			Consumicion cons = (Consumicion) daoStock.get(Consumicion.class, alta.getConsumicion().getIdConsumicion());
			cons.addAltaConsumicion(alta);

			mainFrame.showMessage(MessageType.EXITO,null);
			abrirStock();
			
		}catch(ConstraintViolationException cve){

			mainFrame.showMessage(MessageType.ERROR,null);

			
			for(ConstraintViolation constraintViolation : cve.getConstraintViolations()){
				mainFrame.setErrorMessage(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
			}

		}

	}
	
	@SuppressWarnings("rawtypes")
	public void bajarStock(int rowCombo, Date fecha, int cantidadHeladera, int cantidadDeposito, String comentario){

		if(cantidadDeposito>0 && !ControlSesion.getInstance().getActiveSesion().getUsuario().isAdministrador()){
			//Alguien que no es administrador no puede cargar deposito.
			mainFrame.showMessage(MessageType.ERROR,"OPERACION NO PERMITIDA.");
		}
		else
		try{
			int idConsumicion = availableIds.get(rowCombo);
			Sesion sesion = ControlSesion.getInstance().getActiveSesion();
			Consumicion consumicion = (Consumicion) daoStock.get(Consumicion.class, idConsumicion);
			if(consumicion.getStockHeladera()>=cantidadHeladera && consumicion.getStockDeposito()>=cantidadDeposito){
				BajaConsumicion baja = new BajaConsumicion(consumicion,sesion,cantidadHeladera,cantidadDeposito,0,comentario);
				daoStock.save(BajaConsumicion.class.getName(),baja);
				Consumicion cons = (Consumicion) daoStock.get(Consumicion.class, baja.getConsumicion().getIdConsumicion());
				cons.addBajaConsumicion(baja);
				mainFrame.showMessage(MessageType.CONFIRMACION,null);

			}else{
				mainFrame.showMessage(MessageType.ERROR,"La cantidad en stock es menor a la solicitada");
			}
			
			abrirStock();

		}catch(ConstraintViolationException cve){

			//TODO Verificar que no se necesita rollback en caso de error

			for(ConstraintViolation constraintViolation : cve.getConstraintViolations()){
				mainFrame.setErrorMessage(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
			}

		}

	}
	
	public double obtenerPrecioConsumicion(String nombreConsumicion){
		List <Consumicion> listaConsumiciones = daoStock.list(Consumicion.class.getName());
		for(Consumicion cons: listaConsumiciones){
			if(cons.getNombre().equals(nombreConsumicion))
				return cons.getPrecioUnitario();
		}
		return 0;
	}
	
	public void modificarPrecioConsumicion(double precio, String nombreConsumicion){
		List <Consumicion> listaConsumiciones = daoStock.list(Consumicion.class.getName());
		for(Consumicion cons: listaConsumiciones){
			if(cons.getNombre().equals(nombreConsumicion)){
				cons.setPrecioUnitario(precio);
				daoStock.persist(cons);
			}
		}
		
	}
	
}
